﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace LoRel
{

    [TestClass]
    public class CoreProxyTests
    {
        #region test class and initialization

        internal class TestPosition {
            private readonly String m_Symbol;
            private readonly String m_Trader;
            private readonly int m_Quantity;

            public TestPosition( string symbol, string trader, int quantity ) {
                m_Symbol = symbol;
                m_Trader = trader;
                m_Quantity = quantity;
            }

            public string Symbol { get { return m_Symbol; } }
            public string Trader { get { return m_Trader; } }
            public int Quantity { get { return m_Quantity; } }
        }

        private Core PrepareCore() {
            Core core = new Core();
            core.DeclareField("Symbol", typeof(String));
            core.DeclareField("Trader", typeof(String));
            core.DeclareField("Quantity", typeof(int));
            core.DeclareField("Price", typeof(double));

            core.DeclareColumn("Position", "Symbol");
            core.DeclareColumn("Position", "Trader");
            core.DeclareColumn("Position", "Quantity");

            core.DeclareKeys("Position", new[] { "Symbol", "Trader" });
            return core;
        }

        #endregion

        [TestMethod]
        public void ProxyMapsTypeToTable() {
            Core core = PrepareCore();

            TableReference table = core.GetTable( "Position" );
            core.RegisterProxy( "Position", typeof( TestPosition ) );
            Proxy proxy = core.GetProxy( "Position", typeof( TestPosition ) );
            TestPosition test = new TestPosition( "A", "B", 100 );

            Assert.AreSame( table.Columns[ 0 ], proxy[ 0 ].Column );
            Assert.AreSame( table.Columns[ 1 ], proxy[ 1 ].Column );
            Assert.AreSame( table.Columns[ 2 ], proxy[ 2 ].Column );
        }

        [TestMethod]
        public void ProxyIndiciesAreAlignedToTableColumns()
        {
            Core core = PrepareCore();

            TableReference table = core.GetTable("Position");
            core.RegisterProxy("Position", typeof(TestPosition));
            Proxy proxy = core.GetProxy("Position", typeof(TestPosition));
            for (int i = 0; i < table.Columns.Count; i++)
            {
                Assert.AreSame(table.Columns[i], proxy[i].Column);
            }
        }


        [TestMethod]
        public void KeyProxyIndiciesAreAlignedToTableColumns()
        {
            Core core = PrepareCore();

            TableReference table = core.GetTable("Position");
            core.RegisterProxy("Position", typeof(TestPosition));
            Proxy proxy = core.GetKeyProxy("Position", typeof(TestPosition));
            for (int i = 0; i < table.Keys.Columns.Count; i++)
            {
                Assert.AreSame(table.Keys.Columns[i], proxy[i].Column);
            }
        }

        [TestMethod]
        public void ProxyReturnsCorrectData()
        {
            Core core = PrepareCore();

            TableReference table = core.GetTable("Position");
            core.RegisterProxy("Position", typeof(TestPosition));
            Proxy proxy = core.GetProxy("Position", typeof(TestPosition));
            TestPosition test = new TestPosition("A", "B", 100);

            Assert.AreSame(test.Symbol, proxy[0].Eval(test));
            Assert.AreSame(test.Trader, proxy[1].Eval(test));
            // boxed value  :/
            Assert.AreEqual(test.Quantity, proxy[2].Eval(test));
        }
    }
}
